// ActionScript file
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	public class Player extends Sprite
	{		
		private var bRoleImageLoaded:Boolean;
		
		private const PLAYER_IMAGE_NAME:String = "Sprite.png";
		
		public var canvas:BitmapData;
		public var cvm:Bitmap;
				
		public var spritesheet:BitmapData;
		public var rect:Rectangle;	
		
		//角色目的地
		private var destX:Number = 150;
		private var destY:Number = 150;		
		
		//角色当前动作帧
		private var currentTile:int = 0;		
		
		//角色速度
		private var speed:Number = 150;	
		private var renderCount:int = 0;
		
		//角色动作帧的速度
		private var actSpeed:int = 450/speed;
		
		//角色朝向
		private var direction:int = 0;
		
		//角色起始行走点
		private var beginX:Number = 0;
		private var beginY:Number = 0;
		//内部用
		private var lastMoveTime:int = 0;
		
		//角色状态
		private const PLAYER_STATE_IDLE:int = 0;
		private const PLAYER_STATE_RUN:int = 1;		
		private var playerState:int = PLAYER_STATE_IDLE;
		
		//角色名控件	
		private var txt:TextField;
	
		private var stg:Stage;		
	
		private var _lastMoveTick:int = 0;
		
		//角色是否主视角（一直处于画面中心）
		private var bHero:Boolean = false;
		
		//是否被选中
		private var bFocus:Boolean = false;
		
		//行走路径
		private var walkPath:Array = null;
		private var walkIndex:int = 1;
		
		public var roleID:uint = 0;
		
		public function get lastMoveTick():int
		{
			return _lastMoveTick;
		}
		
		public function set lastMoveTick(_tick:int):void
		{
			_lastMoveTick = _tick;
		}
			
		public function Player(_stg:Stage, playerName:String, pos:Point, _bHero:Boolean= false)
		{	
			bHero = _bHero;

			stg = _stg;
			
			x = pos.x;
			y = pos.y;			
			
			Init(playerName);
			
			stg.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			
		}
		
		public function setFocus():void
		{
			bFocus = true;
			cvm.filters = [new GlowFilter(0xFF0000,1,1.5,1.5,100)];
		}
		
		public function loseFocus():void
		{
			bFocus = false;
			cvm.filters = null;
		}		
		
		public function isOnFocus():Boolean
		{
			return bFocus;
		}
		
		public function onMouseDown(event:MouseEvent):void
		{	
			if(canvas == null || spritesheet == null)
				return;			
			
			var pt:uint = canvas.getPixel32(event.localX, event.localY);
			
			//trace(pt.toString(16));
			if((pt && 0xFF000000) == 0)
			{
				return;
			}
			
			if(!bHero)
			{
				setFocus();
			}
			
			event.stopImmediatePropagation();
			
			//trace("player onMouseDown");
			
			var notifyMove:GameEventDispatcher = new GameEventDispatcher(stg);
			notifyMove.heroSetFocus(this);			
		}
		
		public function Init(playerName:String):void
		{	
			spritesheet = (new ResourceMgr.DefaultRoleImage() as Bitmap).bitmapData;
			
			lastMoveTime = getTimer();
			
			canvas = new BitmapData(150, 150, true, 0xFFFFFF);
			cvm = new Bitmap(canvas, PixelSnapping.ALWAYS, true );
			cvm.filters = null;
			
			addChild(cvm);
					
			// Tile Size
			rect = new Rectangle(0, 0, 150, 150);
			
			txt = new TextField();
			txt.text = playerName;
			txt.textColor = bHero? 0xFFFF00 : 0x0020FF;
			txt.height =20;
			
			txt.x = 60;
			txt.y = 10;
			txt.selectable = false;
			txt.cacheAsBitmap = true;
			
			txt.filters = [new GlowFilter(0x000000,1,1.2,1.2,100)];
			addChild(txt);
			
			if(ResourceMgr.GetInstance().getImage(PLAYER_IMAGE_NAME) == null)
			{
				ResourceMgr.GetInstance().loadImage(PLAYER_IMAGE_NAME);
			}
		}
		
		
		public function unInit():void
		{
			canvas = null;
			spritesheet = null;
			
			removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		private function enterFrameHandler(event:Event):void
		{
			render();
		}		
		
		/*private function updateTargetPos():void
		{			
			if(playerState == PLAYER_STATE_IDLE)
			{
				currentTile = ++currentTile % 5;
			}
			else
			{			
				currentTile = ++currentTile % 8 + 5;			
			}
			
			rect.x = currentTile * 150;				
			rect.y = direction * 150;				
		}*/
		
		
		private function render():void
		{
			if(canvas == null || spritesheet == null)
				return;
			
			var curTime:int = getTimer();
									
			var ri:Number = curTime - lastMoveTime;
			if(ri > 30 )
			{
				++renderCount;
				
				if(renderCount % actSpeed == 0)
				{
					rect.x = (currentTile % 6) * 150;				
					rect.y = direction * 150;				
					
					if(playerState == PLAYER_STATE_IDLE)
					{
						currentTile = 0;
					}
					else
					{			
						currentTile = ++currentTile % 6;			
					}
				}
				
				if(spritesheet != null)
				{
					if(ResourceMgr.GetInstance().getImage(PLAYER_IMAGE_NAME) != null)
					{
						spritesheet = ResourceMgr.GetInstance().getImage(PLAYER_IMAGE_NAME);
						
						canvas.lock();
						canvas.fillRect(new Rectangle(0, 0, 150, 150), 0x000000);
						canvas.copyPixels(spritesheet, rect, new Point(0, 0));		
						canvas.unlock();

					}
					else
					{
						rect.x = 0;
						rect.y = 0;
						//canvas.fillRect(new Rectangle(0, 0, 150, 150), 0x000000);
						canvas.lock();
						canvas.copyPixels(spritesheet, rect, new Point(0, 0));
						canvas.unlock();
					}
				}
				
				DoMove(ri);
				
				lastMoveTime = curTime;
			}
		}		

		
	
		public function get curX():Number
		{
			return x+75;
		}
		
		public function set curX(_x:Number):void
		{
			x = _x-75;
		}
		
		public function get curY():Number
		{
			return y+135;
		}
		
		public function set curY(_y:Number):void
		{
			y = _y-135;
		}		
		
		public function setPath(path:Array):void
		{
			walkPath = path;
			walkIndex = 1;
			if(walkPath != null && walkIndex < walkPath.length)
			{
				MoveTo(walkPath[walkIndex].x, walkPath[walkIndex].y);
				walkIndex++;
			}
		}
		
		public function MoveTo(_x:Number, _y:Number):void
		{
			//if(Math.floor(curX) == Math.floor(_x) && Math.floor(curY) == Math.floor(_x))
			//{
			//	playerState = PLAYER_STATE_IDLE;
			//	return;
			//}
			
			destX = _x;
			destY = _y;
			
			beginX = curX;
			beginY = curY;			
			
			direction = GameGlobals.getDirection(new Point(beginX, beginY), new Point(destX, destY));			
					
			playerState = PLAYER_STATE_RUN;
		}
		
		public function DoMove(t:Number):void
		{	
			//trace(x+","+y);
			
			if(playerState == PLAYER_STATE_IDLE)
				return;
			
			var bp:Point = new Point(curX, curY);
			var target:Point = new Point(destX, destY);
			
			var ptNew:Point=new Point(curX, curY);
			var offset:Point = target.subtract(bp);
			var s:Number=t*speed/1000/offset.length;
			if(s<1)
			{
				ptNew.x+=offset.x*s;
				ptNew.y+=offset.y*s;
			}
			else
			{
				ptNew.x=target.x;
				ptNew.y=target.y;
				
				//继续寻径
				if(walkPath != null && walkIndex < walkPath.length)
				{
					MoveTo(walkPath[walkIndex].x, walkPath[walkIndex].y);
					walkIndex++;
				}
				else
				{
					playerState = PLAYER_STATE_IDLE;
				}
			}			
			
			//trace(s);
			
			var dx:Number = ptNew.x - curX;
			var dy:Number = ptNew.y - curY;
			
			curX = ptNew.x;
			curY = ptNew.y;
			
			if(bHero) //如果是主角，需要通知场景跟着移动
			{
				var notifyMove:GameEventDispatcher = new GameEventDispatcher(stg);
				notifyMove.heroMove(curX, curY);
			}
			
			//trace("(curX:"+curX.toFixed(2)+"curY:"+curY.toFixed(2)+ ") (beginX"+beginX.toFixed(2)+
			//	",beginY:"+beginY.toFixed(2)+") (dx:"+dx.toFixed(2)+",dy:"+dy.toFixed(2)+
			//	") (destX:"+destX.toFixed(2)+", destY:"+destY.toFixed(2)+")\n" );
		}	
				
	}
}